<template>
	<scroll-view scroll-y class="sentence-detail-box" :class="sentenceClass">
		<!-- 隐藏的文本测量元素 -->
		<view class="text-measure" :style="textMeasureStyle" id="textMeasure">{{studyStore.sentence.SentenceEn}}</view>
		<template v-if="actionStep===studyStore.choiceActionStep.TEST_COMPLETE && choiceWords.length > 0">
			<view class="next-tips">接下来将学习如下词汇</view>
			<view class="next-tips-word">
				<u-tag class="word-tag" :text="item.Word" :in-style="tagStyle" type="warning" v-for="item in choiceWords" :key="item.Word" />
				<u-tag v-if="choiceWords.length === 0" class="word-tag" text="恭喜你全部掌握本组词汇" :in-style="tagStyle" type="warning" />
			</view>
		</template>
		<template v-if="actionStep===studyStore.choiceActionStep.TEST_COMPLETE && choiceWords.length === 0">
			<view class="next-tips">恭喜你掌握本句中的词汇</view>
		</template>
		<view class="sentence-detail">
			<u-image class="sentence-img" height="250px" v-if="sentenceImg" :src="sentenceImg" mode="aspectFit"></u-image>
			<view class="sentence-box">
				<view class="sentence" :style="sentenceStyle" id="textContainer">
					<template v-for="(item, _index) in wordIdxList" :key="_index">
						<view @click="handleClickWord(item)" v-if="item.Index !== null" class="word-item real">
							<text class="word" :class="item.isNeedStudy?'font-bold':''" :style="item.style">{{item.text}}</text>
							<text class="sort">{{item.Index}}</text>
						</view>
						<view v-else class="word-item">
							<text style="margin-right: 0.3ch;">{{item.text}}</text>	
							<text class="sort"></text>
						</view>
					</template>
					<u-icon @click="handlePlay" name="volume" color="#5f5d5d" style="margin-left: 14rpx;" size="50"></u-icon>
				</view>
				<view v-if="visibleSentenceCh" class="sentence-zh" :style="sentenceStyle">{{studyStore.sentence.SentenceCn}}</view>
			</view>
		</view>
	</scroll-view>
</template>

<script setup lang="ts">
	import { computed, h, ref, onMounted, watch, nextTick } from 'vue';
	import { ISentence, IWord, IWordIndexExt, useStudyStore } from '@/store/study';
	import { createOptionsMixins, isEmpty, isEmptys, lodash, randomArray } from '@/utils';
	import { useSoundEffect } from '@/common/hooks';
	
	/** 句子组件 */
	defineOptions({
		name: 'sentence',
		inheritAttrs: false,
		options: {
			virtualHost: true
		}
	});
	// 声明组件基本要素
	const emit = defineEmits(['next', 'module-event']);
	const choiceWords = defineModel<IWord[]>('value', { default: () => [] });
	const props = defineProps({
		actionStep: {
			type: String,
			defalut: ''
		}
	})
	
	// hooks 初始化
	const studyStore = useStudyStore();
	const { playMp3 } = useSoundEffect();
	
	// 声明用户变量
	// 测量元素样式
	const textMeasureStyle = ref({
		fontSize: '',
		fontFamily: '',
		fontWeight: ''
	})
	// 句子文本容器的样式
	const sentenceStyle = ref({ justifyContent: 'center' });
	
	const tagStyle = {
		// #ifdef MP
		fontSize: '50rpx',
		marginBottom: '30rpx',
		textAlign: 'center',
		// #endif
	}
	const wordIdxList = ref<any[]>([]);
	const tempChoiceWordIds = ref<IWordIndexExt[]>([]);
	
	// 声明计算属性
	const sentenceClass = computed(() => {
		if (props.actionStep===studyStore.choiceActionStep.TEST_COMPLETE && choiceWords.length > 0) {
			return 'has-btn';
		}
		return '';
	})
	const visibleSentenceCh = computed(() => props.actionStep !== studyStore.choiceActionStep.CHOICE);
	const sentenceImg = computed(() => {
		const img = studyStore.sentence.Media;
		if(img){
			if(img.startsWith('http')){
				return img;
			}
			return `https://nx5.abc5g.com/${img}`;
		}
		return;
	})
	
	const colors = ['#646CFF', '#4B3B0A', '#18a058', '#f0a020', '#d03050', '#D946EF', '#8B5CF6', '#6A0738', '#A70C0C']
	function getDarkRandomColor() {
	    const r = Math.floor(Math.random() * 90 + 90); // 90 to 255
	    const g = Math.floor(Math.random() * 90 + 90); // 90 to 255
	    const b = Math.floor(Math.random() * 90 + 90); // 90 to 255
	    return `rgb(${r}, ${g}, ${b})`;
	}
	const getColors = () => {
		const styles = wordIdxList.value.filter(item => item.style).map(item => item.style)
		if (styles.length === 0) {
			return randomArray(colors)[0];
		}
		
		const unchoice = colors.filter(c => !styles.some((style: string) => style.includes(c)));
		if (unchoice.length > 0) {
			return randomArray(unchoice)[0];
		}
		
		return getDarkRandomColor();
	}
	
	// 声明函数
	// 提交选中的词汇，将命中的索引词汇提交到备用列表
	const commitChoiceWords = () => {
		console.log('commitChoiceWords')
		// 将命中的非扩展索引词汇，转换为 wordGroup 词汇数据
		const formTowordGroup = studyStore.wordGroup.filter(wg => tempChoiceWordIds.value.some(cw => cw.ID === wg.WordId))
		// 获取命中的扩展索引词汇
		const formToIsExt = tempChoiceWordIds.value.filter(cw => !studyStore.wordGroup.some(wg => cw.ID === wg.WordId))
		choiceWords.value = [
			...formTowordGroup,
			...formToIsExt.map(item => {
				return {
					...item,
					WordId: item.ID,
					Media: studyStore.sentence.Media
				}
			})
		]
	}
	
	// 词汇点击事件
	const handleClickWord = (item: any) => {
		if(props.actionStep === studyStore.choiceActionStep.TEST_COMPLETE) {
			return;
		}
		const { Index } = item;
		const filter = studyStore.sentence.WordIds.filter(ids => ids.Index.includes(Index))
		const aboutIndex = [...new Set(filter.flatMap(f => f.Index || []))];
		// 如果命中，熄灭所有与 Index 相关的词
		if (item.active) {
			wordIdxList.value.forEach(position => {
				if (aboutIndex.includes(position.Index)) {
					position.active = false;
					position.style = ''
				}
			})
			tempChoiceWordIds.value = tempChoiceWordIds.value.filter(item => !item.Index.includes(Index));
		} else {
			const color =  getColors();
			wordIdxList.value.forEach(position => {
				if (aboutIndex.includes(position.Index)) {
					position.active = true;
					if (!position.style) {
						//position.style = 'color:#ffffff;background-color:' + color;
						position.style = 'border:1px solid ' + color + ';border-radius: 50%;';
					}
				}
			})
			
			// 案例结构
			// word[1, 3, 16]    a[6, 8, 10, 15]     an[8]         an apply[10, 11]      learn a word[14, 15, 16]    learn[14]     apply[11]     
			// IsExt             !IsExt              IsExt         !IsExt                !IsExt                      IsExt         IsExt   
			// 本体/变体         本体/变体            本体/变体     扩展变体/短语          扩展变体/短语                本体/变体     本体/变体
			// 
			// 1. IsExt 等于 true, 并且其所有索引位置均被包含在 IsExt 等于 false 的词汇内，这种直接筛除掉
			// word[1, 3, 16]    a[6, 8, 10, 15]     an apply[10, 11]      learn a word[14, 15, 16]
			// IsExt             !IsExt              !IsExt                !IsExt                    
			// 本体/变体         本体/变体            扩展变体/短语          扩展变体/短语
		
			// 获取所有的非扩展索引词汇
			const allUnIsExt = studyStore.sentence.WordIds.filter(item => !item.IsExt);
			// 获取有效索引词汇
			const IsValidWordIds = studyStore.sentence.WordIds.filter(item => {
				if (item.IsExt) {
					if (item.Index.every(idx => allUnIsExt.some(ui => ui.Index.includes(idx)))) {
						return false;
					}
				}
				return true;
			});
			// 获取命中的索引词汇
			const hintWordIds = IsValidWordIds.filter(item => item.Index.includes(Index));
			// 差量缓存全部命中的索引词汇
			hintWordIds.forEach(item => {
				if (!tempChoiceWordIds.value.some(cw => cw.ID === item.ID)) {
					tempChoiceWordIds.value.push(item);
				}
			})
		}
		
		// 将命中的索引词汇提交到备用列表
		commitChoiceWords();
		
		nextTick().then(() => {
			console.log('choiceWords.value', choiceWords.value)
		})
	}
	
	const punctuationMark = ['.', ',', '?', '!'];
	const initSentenceWords = () => {
		const sentenceObj = studyStore.sentence;
		// sentenceObj.WordIds
		console.log('sentenceObj.WordIds', sentenceObj.WordIds)
		let tempSentenceEn: string = sentenceObj.SentenceEn || '';
		if (tempSentenceEn) {
			// 建立索引关系
			const sententceWordSp = tempSentenceEn.split(' ');
			wordIdxList.value = sententceWordSp.flatMap((sp, index) => {
				// 是否是必学词(非扩展词)
				const isNeedStudy = sentenceObj.WordIds.some(wi => wi.Index.includes(index + 1) && !wi.IsExt)
				if (punctuationMark.some(mark => sp.endsWith(mark))) {
					const word = sp.substring(0, sp.length - 1);
					const mark = sp.substring(sp.length - 1);
					return [
						{ Index: index + 1, text: word, isNeedStudy },
						{ Index: null, text: mark },
						{ Index: null, text: ' ' }
					]
				}
				
				return [
					{ Index: index + 1, text: sp, isNeedStudy },
					{ Index: null, text: ' ' }
				]
			})
		}
	}
	
	// 初始化测量元素的样式，使其与容器保持一致
	const initMeasureStyle = () => {
		const query = uni.createSelectorQuery();
		// 获取文本容器的样式
		query.select('#textContainer').boundingClientRect()
			.select('#textContainer').fields(
				{ computedStyle: ['fontSize', 'fontFamily', 'fontWeight'] },
				function(res: any){
					if(res){
						// console.log('res', res)
						const style =  {
							...textMeasureStyle.value
						}
						
						if(!isEmpty(res.fontSize)){
							style.fontSize = res.fontSize;
						}
						if(!isEmpty(res.fontFamily)){
							style.fontFamily = res.fontFamily;
						}
						if(!isEmpty(res.fontWeight)){
							style.fontWeight = res.fontWeight;
						}
						
						textMeasureStyle.value = style;
					}

					// 样式设置完成后检查对齐方式
					checkTextAlignment()
				}
			).exec();
	}

	// 样式设置完成后检查对齐方式
	const checkTextAlignment = () => {
		const query = uni.createSelectorQuery();
		    
		// 同时获取容器和测量元素的宽度
		query.select('#textContainer').boundingClientRect()
			.select('#textMeasure').boundingClientRect()
			.exec((res) => {
				if (res && res.length >= 2) {
					if(!isEmptys([res[0], res[1]])){
						const containerWidth = res[0].width;
						const textWidth = res[1].width;
						
						// 根据宽度比较结果设置对齐方式
						if (textWidth <= containerWidth) {
							sentenceStyle.value.justifyContent = 'center';
						} else {
							sentenceStyle.value.justifyContent = 'flex-start';
						}
					}
				}
			});
	}
	
	function handlePlay() {
		console.log('handlePlay', studyStore.sentence.Audio)
		playMp3(studyStore.sentence.Audio);
	}


	watch(
		() => studyStore.sentence, 
		() => initSentenceWords(), 
		{ deep: true, immediate: true }
	)

	/** 生命周期钩子函数：页面加载完毕 */
	onMounted(() => {
		initMeasureStyle();
	})
	
</script>

<style lang="scss">
	.sentence-detail-box{
		--font-color: #332c2b;
		display: flex;
		flex-flow: column;
	}
	
	/* #ifdef H5 */
	.sentence-detail-box{ height: calc(100vh - 190px); }
	.sentence-detail-box.has-btn{ height: calc(100vh - 190px); }
	/* #endif */
	
	/* #ifdef MP */
	.sentence-detail-box{ height: calc(100vh - 440rpx); }
	.sentence-detail-box.has-btn{ height: calc(100vh - 440rpx); }
	/* #endif */
	
	
	/* 测量元素样式 - 绝对定位并隐藏 */
	.text-measure {
		position: absolute;
		visibility: hidden;
		white-space: nowrap;
		/* 移到可视区域外 */
		top: -1000rpx;
	}
	
	.sentence-img {
		--imgWidth--Be--detailWidth: 0.6125;
		--imgHeight--Be--imgWidth: 0.7092;
	
		width: calc(100vw*var(--imgWidth--Be--detailWidth)) !important;
		height: calc(100vw*var(--imgWidth--Be--detailWidth)*var(--imgHeight--Be--imgWidth)) !important;
		border-radius: 36rpx !important;
		margin: 0 auto;
	}
	
	.sentence-box {
		margin-top: 24rpx;
		font-size: 32rpx;
		
		.word-item{
			display: flex;
			flex-flow: column;
			align-items: center;
			
			.word{
				height: 44rpx;
				border: 1px solid transparent;
				border-bottom: 1px solid;
				display: flex;
				align-items: center;
			}
			.sort{
				height: 44rpx;
			}
		}
		.word-item.real{
			.word{
				padding-left: 0.3ch;
				padding-right: 0.3ch;
			}
		}
		::v-deep(.word){
			&.active{
			    background: url(https://nx5.abc5g.com/res/static/class/choice-bg.png);
			    background-size: 100% 100%;
			}
		}
		
		.sentence{
			display: flex;
			flex-wrap: wrap;
			color: var(--font-color);
		}
		.sentence-zh{
			display: flex;
			flex-wrap: wrap;
			color: #a1a1a1;
			margin-top: 12rpx;
			text-indent: 2em;
		}
	}
	
	
	.next-tips{
		text-align: center;
		font-size: 50rpx;
		margin-top: 16px;
	}
	.next-tips-word{
		text-align: center;
		margin-top: 50rpx;
	}
	
	.next-tips-word .word-tag{
		margin-bottom: 10rpx;
		/* #ifdef MP */
		margin-right: 40rpx;
		/* #endif */
	}
	
	.word-tag-content{
		/* #ifdef MP */
		font-size: 50rpx !important;
		/* #endif */
	}
	.next-tips-word .u-size-default{
		font-size: 50rpx !important;
		padding-bottom: 20rpx;
		margin-right: 40rpx;
	}
	

	/* 针对 1280px 分辨率 */
	@media(min-width:1200px) {
		
		.sentence-img {
			width: calc(1200rpx*var(--imgWidth--Be--detailWidth)) !important;
			height: calc(1200rpx*var(--imgWidth--Be--detailWidth)*var(--imgHeight--Be--imgWidth)) !important;
		}
		
		.sentence-box {
			margin-top: 38rpx;
			font-size: 40rpx;
		}
		
		.next-tips{
			font-size: 60rpx;
			margin-top: 100rpx;
		}
		.next-tips-word{
			padding-top: 50rpx;
		}
		.next-tips-word .word-tag{
			margin-bottom: 10rpx;
			/* #ifdef MP */
			padding-bottom: 20rpx;
			margin-right: 40rpx;
			
			::v-deep(.u-size-default){
				font-size: 60rpx !important;
			}
			/* #endif */
		}
		.next-tips-word .u-size-default{
			font-size: 60rpx !important;
			padding-bottom: 20rpx;
			margin-right: 40rpx;
		}
	}
</style>